﻿using System;
using Scrum.Net.Interfaces;
using Scrum.Net.Utilities;

namespace Scrum.Net.Classes
{
    public class SprintAvailability : ObservableObject, ISprintAvailability
    {
        private readonly ISprint _sprint;
        private readonly IUser _user;

        public IUser User
        {
            get { return _user; }
        }

        public int TotalDays { get; private set; }

        public float TotalHours { get; private set; }

        public int DaysOff { get; private set; }

        public int ActualDays
        {
            get { return TotalDays - DaysOff; }
        }

        public float PlannedHours
        {
            get { throw new NotImplementedException(); }
        }

        public float RestAvailableHours
        {
            get { throw new NotImplementedException(); }
        }

        public SprintAvailability(ISprint sprint, IUser user)
        {
            _sprint = sprint;
            _user = user;

            CalculatingAvailabilty();
        }

        public void CalculatingAvailabilty()
        {
            TotalDays = CalculateTotalDays();
            DaysOff = CalculatateDaysOff();
            TotalHours = CalculateTotalHours();

            RaisePropertyChanged("TotalDays");
            RaisePropertyChanged("DaysOff");
            RaisePropertyChanged("ActualDays");
            RaisePropertyChanged("TotalHours");
        }

        /// <summary>
        /// needs Sprint Start and EndDate, maybe days of week (now fix 5)
        /// </summary>
        /// <returns>Total days of the user</returns>
        private int CalculateTotalDays()
        {
            int days = 0;
            DateTime date = _sprint.StartDate;

            do
            {
                if (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday)
                {
                    days++;
                }

                date = date + new TimeSpan(1,0,0,0);
            } while (date <= _sprint.EndDate);

            return days;
        }

        private int CalculatateDaysOff()
        {
            int days = 0;

            for (DateTime i = _sprint.StartDate; i < _sprint.EndDate; i = i + new TimeSpan(1,0,0,0))
            {
                if (_user.DaysOff.ContainsKey(i))
                {
                    days++;
                }
            }

            return days;
        }

        private float CalculateTotalHours()
        {
            if (_user.AvailableHours > 0 && ActualDays > 0)
            {
                return ActualDays * _user.AvailableHours;
            }

            return 0;
        }
    }
}